package com.jasonzqshen.ifm.featureModelCore;

import java.util.Collection;
import java.util.LinkedList;

import org.w3c.dom.Element;

import com.jasonzqshen.ifm.collections.treeCollection.*;
import com.jasonzqshen.ifm.collections.treeCollection.factories.TreeNodeFactory;
import com.jasonzqshen.ifm.featureModelCore.FMTypes.*;
import com.jasonzqshen.ifm.featureModelCore.arguments.*;
import com.jasonzqshen.ifm.featureModelCore.featureModelInterface.*;
import com.jasonzqshen.ifm.featureModelCore.shapes.*;
import com.jasonzqshen.ifm.utils.Identifier;

public final class FeatureTreeGroupRelationship extends TreeNode {

    public static final TreeNodeFactory FACTORY = new TreeNodeFactory(
            FeatureTreeGroupRelationship.class.getName()) {

        @Override
        public FeatureTreeGroupRelationship constructNewInstance(Identifier id,
                Object[] args) {
            if (args == null || args.length != 1
                    || !(args[0] instanceof FMTreeGroupRelationshipType)) {
                return new FeatureTreeGroupRelationship(id,
                        FMTreeGroupRelationshipType.GroupMandatory);
            }

            FMTreeGroupRelationshipType type = (FMTreeGroupRelationshipType) args[0];
            FeatureTreeGroupRelationship gRelationship = new FeatureTreeGroupRelationship(
                    id, type);
            return gRelationship;
        }

        @Override
        /**
         * XML parser
         * 
         * @param xelem
         * @param obj
         * @throws TreeCollectionException
         */
        public void xmlParser(Element elem, TreeObject treeObject) {
            if (!(treeObject instanceof FeatureTreeGroupRelationship)) {
                return;
            }

            FeatureTreeGroupRelationship gRelationship = (FeatureTreeGroupRelationship) treeObject;
            gRelationship.type = Enum.valueOf(
                    FMTreeGroupRelationshipType.class,
                    elem.getAttribute(XML_TYPE));
            gRelationship.circle = FMCircle.parseXElem(elem);
        }

    };

    private static final String XML_TYPE = "GroupRelationshipType";

    private FMTreeGroupRelationshipType type;

    private FMCircle circle;

    public FeatureTreeGroupRelationship(Identifier id,
            FMTreeGroupRelationshipType type) {
        super(id);
        this.type = type;
    }

    /**
     * Get Feature Tree Group Relationship Type.
     * 
     * @return
     */
    public FMTreeGroupRelationshipType getRelationshipType() {
        return this.type;
    }

    /**
     * Set Relationship Type
     */
    public void setRelationshipType(FMTreeGroupRelationshipType newType) {
        RelationshipTypeChangedArgs args = new RelationshipTypeChangedArgs(
                this, newType);

        this.treeOwner.beforeProcess(this, args);
        this.type = newType;
        this.treeOwner.afterProcess(this, args);
    }

    /**
     * get children nodes
     * 
     * @return
     */
    public Collection<FeatureTreeNode> getChildrenNodes() {
        LinkedList<FeatureTreeNode> nodes = new LinkedList<FeatureTreeNode>();
        for (NonRoot child : this.children.values()) {
            if (child instanceof FeatureTreeNode) {
                nodes.add((FeatureTreeNode) child);
            }
        }
        return nodes;
    }

    /**
     * Get parent node
     * 
     * @return
     */
    public Feature getParentNode() {
        return (Feature) this.parent;
    }

    /**
     * Get shape
     * 
     * @return
     */
    public FMCircle getShape() {
        return this.circle;
    }

    /**
     * Set shape
     * 
     * @param circle
     */
    public void setShape(FMCircle circle) {
        this.circle = circle;
    }

    /**
     * Parse to element
     * 
     * @throws TreeCollectionException
     */
    public Element toXElem() throws TreeCollectionException {
        Element xelem = super.toXElem();
        xelem.setAttribute(XML_TYPE, this.type.toString());
        return xelem;
    }


    /**
     * Equals
     */
    @Override
    public boolean equals(Object obj) {
        boolean flag = super.equals(obj);
        if (flag == false) {
            return flag;
        }
        if (!(obj instanceof FeatureTreeGroupRelationship)) {
            return false;
        }

        FeatureTreeGroupRelationship gRelationship = (FeatureTreeGroupRelationship) obj;
        return this.type == gRelationship.type
                && this.circle.equals(gRelationship.circle);
    }
}
